package xyz.scootaloo.code.draft

import java.lang.IllegalArgumentException

/**
 * @author flutterdash@qq.com
 * @since 2021/11/7 21:23
 */


class MultiSystemKeyMapper<T>(
    private val mapper: MutableList<T> = ArrayList(),
    private val getValue: (T) -> String
) {
    private val stepSize = 10 + 26 + 26

    fun refresh(new: List<T>) {
        mapper.clear()
        mapper.addAll(new)
    }

    fun getItems(key: String): List<String> {
        val fragments = key2array(key)
        return try {
            array2items(fragments)
        } catch (e: IndexOutOfBoundsException) {
            throw IllegalArgumentException("数值大于 ${mapper.size}^2-1")
        }
    }

    fun getKeyOf(items: List<T>) {
        val set = HashSet<T>(items)
    }

    private fun array2items(array: IntArray): List<String> {
        val items = ArrayList<String>()
        var step = 0
        for (idx in array.size - 1 downTo 0) {
            val element = array[idx]
            var comparator = 1
            repeat(6) {
                if (comparator and element != 0) {
                    items.add(getValue(mapper[step + it]))
                }
                comparator = comparator.shl(1)
            }
            step += stepSize
        }
        return items
    }

    private fun key2array(key: String): IntArray {
        val fragments = IntArray(key.length)
        for (idx in key.length - 1 downTo 0) {
            fragments[idx] = when (val ch = key[idx]) {
                in '0'..'9' -> (ch - '0')
                in 'a'..'z' -> (ch - 'a' + 10)
                in 'A'..'Z' -> (ch - 'A' + 10 + 26)
                else -> {
                    throw IllegalArgumentException("`$ch`不在处理范围内")
                }
            }
        }
        return fragments
    }
}

data class Role(
    val id: Int,
    val name: String
)

fun main() {
    val read = Role(1, "read")
    val write = Role(2, "write")
    val execute = Role(3, "execute")
    val mapper = MultiSystemKeyMapper<Role> { it.name }
    mapper.refresh(listOf(read, write, execute))
    for (i in 0..7) {
        println(mapper.getItems("$i"))
    }
}
